Although implementations of shared memory segment across programs have been around for decades and the technology to support it is now well-established, transposing this idea to modern type-safe programming language with dynamic class loading, multiple user-defined name space and automated memory management, such as the Java programming language (JAVA), is difficult.
JAVA is a strongly typed object-oriented programming language. As such, JAVA enforces safety mechanisms that prevent type-incompatible operations from being performed on data. Specifically, the JAVA runtime environment does not allow an application to perform an operation on an object that is not defined by the type of the object. In JAVA, class types are created dynamically, at program execution. A class type is defined via a class loader. The class loader locates and provides, on-demand, the Java Virtual Machine (JVM) with a class file that contains the binary representation of classes, out of which the JVM creates runtime class types. A class type is identified by both (a) the fully qualified name of the class, and (b) the class loader that is associated with that class. Current specifications of the JVM define three platform-defined class loaders organized in a delegation hierarchy: a class loader in the hierarchy always delegates a request for loading a class to its parent first, and only tries to locate a class file itself if the parent failed to find one. The root of the class loader hierarchy is the bootstrap class loader (also called the primordial loader).
The bootstrap class loader is a built-in class loader used to load the base classes that are intimately associated with a JVM implementation and are essential to its functioning (such as classes of the java.lang. *packages). Every program has a bootstrap loader. The bootstrap loader always retrieves the binary representation of classes from the same location (rt. jar, in the case of Sun's HotSpot implementation of the JVM). Further, the bootstrap loader never delegates the resolution of symbolic references. Thus, symbolic references from classes defined by the bootstrap loader always resolve to the same binary representations (which for a given installation of the Java Platform never change), and therefore, to the same runtime representations.
In addition to the three platform-defined class loaders (bootstrap, extension, and system class loaders), each program may create additional class loaders and define their behavior. In general, there is no guarantee that two non-bootstrap class loaders can resolve the same class name to the same class runtime representation for a given class name.
Applications written in JAVA can be executed as “isolates.” Isolates are abstract run-time constructs that represent applications (programs) that execute independently from each other. Each isolate has its own private memory area which that isolate, and no other application, can access. For each isolate, the JAVA runtime environment prevents applications other than that isolate from accessing that isolate's data. Isolates run independently of each other.
The features of the Java programming language make sharing across applications difficult and require more than the ability to allocate objects in a memory area shared between isolated applications. Theoretically, a first isolate might be designed to create an object in a designated memory area that is shareable between isolates. The class type of the object would be defined by a class loader created by the first isolate, therefore both the class loader and the runtime representation of the class type would reside in a memory area private to the first isolate, and the first isolate would be able to understand and use the object stored in the designated memory area. Unfortunately, even if a second isolate could obtain a reference to the object that was stored in the designated memory area, the second isolate would not be able to use the object without first understanding the object's type. The second isolate would be unable to understand the object's type without accessing the object's type runtime representation or invoking the class loader that defined the object's type if symbolic links are unresolved. Because both of these are located in memory areas private to the first isolate (in particular, its heap), the second isolate cannot use the object created by the first one.
Even if the second isolate were somehow permitted to access the first isolate's private memory area where the object type representation is stored, the second isolate would be unable to do so unless the first isolate was still executing at the time that the second isolate needed to access the object in the designated memory area. If the first isolate were to create the object in the designated memory area and then terminate, leaving the object in the designated memory area, other applications would have no means of understanding that object's type after the first isolate's termination. When an application terminates, the class loaders privately defined by that application vanish. The inability of any application to use an object created by another application except while that other application is still executing would be intolerably restrictive in most cases.